contents

객체지향 프로그래밍에서 자주 쓰이는 디자인 패턴들을 설명하겠습니다. 디자인 패턴은 크게 생성 패턴(Creational), 구조 패턴(Structural), 행위 패턴(Behavioral) 세 가지로 나눌 수 있습니다.


1. 생성 패턴 (Creational Patterns)

주요 생성 패턴


2. 구조 패턴 (Structural Patterns)

주요 구조 패턴


3. 행위 패턴 (Behavioral Patterns)

주요 행위 패턴


요약

패턴 분류 주요 패턴 역할 및 목적
생성 패턴 Singleton, Factory Method, Builder, Prototype 객체 생성 과정 캡슐화 및 관리
구조 패턴 Adapter, Composite, Decorator, Facade, Proxy 객체 구성 및 인터페이스 단순화
행위 패턴 Observer, Strategy, Command, State, Chain of Responsibility 객체 간 상호작용 및 행위 관리

여기서는 일곱 가지 대표적인 객체지향 디자인 패턴(싱글톤, 팩토리 메서드, 옵저버)을 Java 코드로 예제로 보여드리겠습니다.


1. 싱글톤 패턴 (Singleton Pattern)

// Singleton 클래스
public class Singleton {
    private static Singleton instance; // 유일한 인스턴스

    private Singleton() {} // 생성자 private

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton(); // 최초 1회만 생성
        }
        return instance;
    }
}

// 사용 예시:
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
System.out.println(s1 == s2); // true

2. 팩토리 메서드 패턴 (Factory Method Pattern)

// Product 인터페이스 및 구현체
interface Animal {
    void speak();
}

class Dog implements Animal {
    public void speak() { System.out.println("멍멍!"); }
}

class Cat implements Animal {
    public void speak() { System.out.println("야옹!"); }
}

// 팩토리 클래스
class AnimalFactory {
    public static Animal createAnimal(String type) {
        if (type.equals("dog")) return new Dog();
        else if (type.equals("cat")) return new Cat();
        else throw new IllegalArgumentException("Unknown type");
    }
}

// 사용 예시:
Animal a = AnimalFactory.createAnimal("dog");
a.speak(); // "멍멍!"

3. 옵저버 패턴 (Observer Pattern)

import java.util.*;

// 옵저버(구독자) 인터페이스
interface Observer {
    void update(String news);
}

// 구독자 구현체
class NewsReader implements Observer {
    private String name;
    public NewsReader(String name) { this.name = name; }

    public void update(String news) {
        System.out.println(name + "가 뉴스를 받았습니다: " + news);
    }
}

// 주제(발행자) 클래스
class NewsAgency {
    private List<Observer> observers = new ArrayList<>();

    public void addObserver(Observer o) { observers.add(o); }
    public void removeObserver(Observer o) { observers.remove(o); }

    public void notifyObservers(String news) {
        for (Observer o : observers) {
            o.update(news);
        }
    }
}

// 사용 예시:
NewsAgency agency = new NewsAgency();
observer1 = new NewsReader("홍길동");
observer2 = new NewsReader("김영희");
agency.addObserver(observer1);
agency.addObserver(observer2);

agency.notifyObservers("자바 디자인 패턴 강의 시작!"); 
// 홍길동가 뉴스를 받았습니다: 자바 디자인 패턴 강의 시작!
// 김영희가 뉴스를 받았습니다: 자바 디자인 패턴 강의 시작!

4. 데코레이터 패턴 (Decorator Pattern)

기존 객체에 동적으로 기능을 추가하는 패턴입니다.

// 기본 컴포넌트 인터페이스
interface Coffee {
    String getDescription();
    int getCost();
}

// 구체 컴포넌트
class BasicCoffee implements Coffee {
    public String getDescription() { return "커피"; }
    public int getCost() { return 2000; }
}

// 데코레이터
class MilkDecorator implements Coffee {
    private Coffee coffee;
    public MilkDecorator(Coffee coffee) { this.coffee = coffee; }
    public String getDescription() { return coffee.getDescription() + "+우유"; }
    public int getCost() { return coffee.getCost() + 500; }
}

// 사용 예시
Coffee coffee = new BasicCoffee();
coffee = new MilkDecorator(coffee);
System.out.println(coffee.getDescription()); // 커피+우유
System.out.println(coffee.getCost()); // 2500

5. 전략 패턴 (Strategy Pattern)

행동(알고리즘)을 객체로 분리하여 런타임에 교체하는 패턴입니다.

interface SortStrategy {
    void sort(int[] arr);
}

class BubbleSort implements SortStrategy {
    public void sort(int[] arr) { System.out.println("버블 정렬"); }
}

class QuickSort implements SortStrategy {
    public void sort(int[] arr) { System.out.println("퀵 정렬"); }
}

class Sorter {
    private SortStrategy strategy;
    public Sorter(SortStrategy strategy) { this.strategy = strategy; }
    public void sort(int[] arr) { strategy.sort(arr); }
}

// 사용 예시
Sorter sorter = new Sorter(new BubbleSort());
sorter.sort(new int[]{5,2,3}); // 버블 정렬
sorter = new Sorter(new QuickSort());
sorter.sort(new int[]{5,2,3}); // 퀵 정렬

6. 컴포지트 패턴 (Composite Pattern)

트리 구조 객체를 단일 객체처럼 다루고 싶을 때 사용하는 패턴입니다.

import java.util.ArrayList;
import java.util.List;

interface Component {
    void show();
}

class Leaf implements Component {
    private String name;
    public Leaf(String name) { this.name = name; }
    public void show() { System.out.println(name); }
}

class Composite implements Component {
    private List<Component> children = new ArrayList<>();
    public void add(Component c) { children.add(c); }
    public void show() {
        for (Component c : children)
            c.show();
    }
}

// 사용 예시
Composite root = new Composite();
root.add(new Leaf("Leaf1"));
Composite branch = new Composite();
branch.add(new Leaf("Leaf2"));
branch.add(new Leaf("Leaf3"));
root.add(branch);
root.show(); // Leaf1, Leaf2, Leaf3

7. 퍼사드 패턴 (Facade Pattern)

여러 복잡한 서브시스템을 간단한 인터페이스로 감싸주는 패턴입니다.

class Cpu { void start() { System.out.println("CPU 시작"); } }
class Memory { void load() { System.out.println("메모리 로드"); } }
class ComputerFacade {
    private Cpu cpu = new Cpu();
    private Memory memory = new Memory();
    public void start() {
        cpu.start();
        memory.load();
        System.out.println("컴퓨터 동작");
    }
}

// 사용 예시
ComputerFacade computer = new ComputerFacade();
computer.start(); // CPU 시작, 메모리 로드, 컴퓨터 동작

references